#include "riscv.h"
#include "common.h"

// 表示S模式的主程序，从M模式切换到S模式时执行该程序，由mret执行时mepc寄存器的值决定
volatile static int started = 0;   // 标志内核是否启动完成
// 每个CPU核心都要执行
void main() {
    // hart0执行初始化
    int hartid = r_tp();
    if(hartid == 0) {
        printfinit();             // 初始化printf
        printf("**************************\n");
        printf("      欢迎进入OKOS！\n");
        printf("**************************\n");
        kinit();                  // 初始化物理内存分配器
        kvminit();                // 初始化内核页表
        kvminithart();            // hart0切换到内核页表并启动分页
        procinit();               // 初始化进程表
        trapinithart();           // 初始化内核程序陷入地址
        procinituser();           // 初始化第一个用户进程
        // 手动触发一个非法指令异常
        //asm volatile(".word 0xffffffff");
        __sync_synchronize();
        started = 1;              // 内核初始化完成
    } else {
        // 内核初始化过程中其他hart进入低功耗等待状态
        while(started == 0) 
            ;
        __sync_synchronize();
        kvminithart();             // 其他hart初始化
        trapinithart();            // 初始化内核程序陷入地址
    }
    scheduler();                  // 启动调度器
}